package org.dromara.easytl;

import java.util.HashMap;
import java.util.Map;

/**
 * 模板上下文
 * <p>
 * 用于存储模板渲染时需要的变量和对象，支持嵌套作用域
 * </p>
 * 
 * @author gongjun
 * @since 1.0.0
 */
public class Context {

    /**
     * 当前作用域的变量存储
     */
    private final Map<String, Object> variables;

    /**
     * 父级作用域
     */
    private final Context parent;

    /**
     * 构造函数，创建根作用域
     */
    public Context() {
        this(null);
    }

    /**
     * 构造函数，创建子作用域
     * 
     * @param parent 父级作用域
     */
    public Context(final Context parent) {
        this.variables = new HashMap<>();
        this.parent = parent;
    }

    /**
     * 添加变量到上下文
     * 
     * @param name 变量名
     * @param value 变量值
     */
    public void put(final String name, final Object value) {
        variables.put(name, value);
    }

    /**
     * 从上下文获取变量
     * <p>
     * 如果当前作用域找不到变量，会向上查找父级作用域
     * </p>
     * 
     * @param name 变量名
     * @return 变量值，如果不存在则返回 null
     */
    public Object get(final String name) {
        if (variables.containsKey(name)) {
            return variables.get(name);
        }
        if (parent != null) {
            return parent.get(name);
        }
        return null;
    }

    /**
     * 检查变量是否存在
     * <p>
     * 如果当前作用域找不到变量，会向上查找父级作用域
     * </p>
     * 
     * @param name 变量名
     * @return 如果变量存在返回 true，否则返回 false
     */
    public boolean contains(final String name) {
        if (variables.containsKey(name)) {
            return true;
        }
        if (parent != null) {
            return parent.contains(name);
        }
        return false;
    }

    /**
     * 从当前作用域移除变量
     * 
     * @param name 变量名
     * @return 被移除的变量值，如果不存在则返回 null
     */
    public Object remove(final String name) {
        return variables.remove(name);
    }

    /**
     * 创建子作用域
     * 
     * @return 新的子作用域
     */
    public Context createChildContext() {
        return new Context(this);
    }

    /**
     * 获取父级作用域
     * 
     * @return 父级作用域，如果是根作用域则返回 null
     */
    public Context getParent() {
        return parent;
    }

    /**
     * 清空当前作用域的所有变量
     */
    public void clear() {
        variables.clear();
    }

    /**
     * 获取当前作用域的所有变量（不包括父级作用域）
     * 
     * @return 变量映射的副本
     */
    public Map<String, Object> getVariables() {
        return new HashMap<>(variables);
    }
}

